
package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.SQLException;
import java.util.Timer;
import java.util.TimerTask;

import javax.security.auth.login.LoginException;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.border.EmptyBorder;

import rmi.Login;
import rmi.Session;
import stuff.Result;

public class GUIHome extends GUIMain{
	
	private static final long serialVersionUID = 1L;
	private JFrame myFrame;
	private Registry reg;
	private Session temp;
	private GUIHomeLeft left;
	private GUIHomeRight right;
	private GUILogin dialog;
	private Timer timer;
	private int timerCounter = 0;
	private String port, ip;
	
	public GUIHome(JFrame param, int cornerIndex){
		super(param, cornerIndex);
		this.myFrame = param;
		this.setTitle("GIAO DIỆN CHUNG");
		param.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.bottomPanel.setOpaque(false);
		this.bottomPanel.setLayout(new GridBagLayout());
		//GUI
		left = new GUIHomeLeft();
		right = new GUIHomeRight();
		
		right.setPreferredSize(new Dimension(200, 0));
		
		this.bottomPanel.setLayout(new BorderLayout(10,5));
		this.bottomPanel.setOpaque(false);
		this.bottomPanel.setBorder(new EmptyBorder(0, 10, 10, 10));
		
		this.bottomPanel.add(left,BorderLayout.CENTER);
		this.bottomPanel.add(right,BorderLayout.EAST);
		
		this.myFrame.addWindowListener(new WindowAdapter() {

			@Override
			public void windowActivated(WindowEvent e) {
				super.windowActivated(e);
				if(dialog == null) return;
				if(dialog.isShowing()){
					dialog.setVisible(true);
				}
			}
			
		});
		this.exitButton.setAction(new CloseAction());
		//LOGINFORM
		dialog = new GUILogin(myFrame,this);	
		dialog.setSize(new Dimension(350, 180));
		dialog.setLocationRelativeTo(myFrame);
		dialog.setVisible(true);
	}
	
	public Result login(String username, String pass){
		File ipFile = new File("ipConfig.dbz");
		if(ipFile.exists()){
			System.out.println("existed");
			try {
				DataInputStream is = new DataInputStream(new FileInputStream(ipFile));
				port = is.readUTF();
				ip = is.readUTF();
				is.close();
			} catch (IOException e) {
				return new Result(false, "Có lỗi khi đọc tập tin ipConfig.dbz");
			}
			
		}else{
			return new Result(false, "Không Có cấu hình ip máy chủ .");
		}
		
		try {
			System.setProperty("java.rmi.server.hostname", ip);
			reg = LocateRegistry.getRegistry(ip, Integer.parseInt(port));
			Login stub = (Login) reg.lookup("Login");
			temp = (Session) stub.login(username, pass.toCharArray());
			if(temp == null){
				return new Result(false, "Đăng nhập không thành công.");
			}
			doShowingInfo();
			doLogInStuff();
			left.DoingRandom(temp);
			//checkServer();
			return new Result(true, "Đăng nhập thành công");
		} catch(java.rmi.ConnectException connectex){
			connectex.printStackTrace();
			return new Result(false, "Không tìm thấy thông tin về máy chủ.");
		}
		catch (LoginException loginex){
			return new Result(false, "Không thể kết nối tới máy chủ.");
		}
		catch (NotBoundException ex){
			return new Result(false, "Đã kết nối tới máy chủ nhưng thao tác đăng nhập không thành công.");
		}
		catch (AlreadyBoundException e) {
			return new Result(false, "Người dùng đã đăng nhập.");
		}
		catch (RemoteException e) {
			return new Result(false, "Lỗi không xác định xảy ra.");
		}
	}
	
	private void doLogInStuff(){
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				try {
					if(timerCounter==2){
						checkServer();
						timerCounter = 0;
					}else{
						if(left.getWhatIsShowing() == GUIHomeLeft.EXAM_SHOWING){
							right.reduceOneSec();
						}else{
							right.setRemainingTime(0);
						}
						timerCounter++;
					}
				} catch (RemoteException e) {
					String output = "Kết nối tới máy chủ bị gián đoạn. Nhấn OK để thoát chương trình.";
					JOptionPane.showMessageDialog(myFrame, output, "Thông báo", JOptionPane.ERROR_MESSAGE);
					System.exit(-1);
				}
			}
		};
		
		timer = new Timer();
		timer.schedule(	task, 0, 1000l);
	}
	
	private void checkServer() throws RemoteException{
		if(temp.canDoExam()){
			if(left.getWhatIsShowing() != GUIHomeLeft.EXAM_SHOWING){
				JOptionPane.showMessageDialog(myFrame, 
						"Khoá thi của bạn đã được mở.\nNhấn OK để tiến hành vào khu vực thi.", 
						"Thông báo" , JOptionPane.INFORMATION_MESSAGE);
				left.DoingExam(temp);
			}
			right.setRemainingTime(temp.getRemainTime());
		}else{
			double x;
			try {
				x = temp.getMark();
			} catch (SQLException e) {
				e.printStackTrace();
				return;
			}
			if(x != -1){
				if(left.getWhatIsShowing()!= GUIHomeLeft.MARK_SHOWING){
					left.DoingMark(temp);
					left.revalidate();
					left.repaint();
				}
			}
		}
	}
	
	private void doShowingInfo(){
		try {
			right.setMSTS(temp.getMSTS());
			right.setName(temp.getStudentFirstName() + " " + temp.getStudentLastName());
			right.setCMND(temp.getCMND());
			right.setDateOfBirth(temp.getDateOfBirth());
			right.setRoom(temp.getRoom());
			setTitle(temp.getCourseTitle());
		} catch (RemoteException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, 
					"Có lỗi xảy ra khi lấy thông tin sinh viên từ máy chủ.", 
					"Thông báo", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	class CloseAction extends AbstractAction{

		private static final long serialVersionUID = 1L;

		@Override
		public void actionPerformed(ActionEvent e) {
			if(temp == null){
			}else{
				try {
					temp.logout();
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
			}
			System.exit(1);
		}
	}
}
